package org.ithang.application.btRecord.service;

import java.util.List;
import java.util.Map;

import org.apache.http.impl.client.AIMDBackoffManager;
import org.apache.log4j.Logger;
import org.ithang.application.account.bean.Account;
import org.ithang.application.account.service.AccountService;
import org.ithang.application.btAddr.bean.BtAddr;
import org.ithang.application.btAddr.service.BtAddrService;
import org.ithang.application.btRecord.bean.BtRecord;
import org.ithang.application.btRecord.mapper.BtRecordMapper;
import org.ithang.application.charge.bean.Charge;
import org.ithang.application.charge.service.ChargeService;
import org.ithang.application.customer.bean.Customer;
import org.ithang.system.keyvalue.bean.Keyvalue;
import org.ithang.system.keyvalue.service.KeyvalueService;
import org.ithang.tools.database.ModelDao;
import org.ithang.tools.eth.ETHInfo;
import org.ithang.tools.eth.ETHUtil;
import org.ithang.tools.lang.DateUtils;
import org.ithang.tools.model.ActionResult;
import org.ithang.tools.model.Arith;
import org.ithang.tools.model.ErrorInfo;
import org.ithang.tools.model.Pager;
import org.ithang.tools.redis.Keys;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 提币记录 服务
 * @author zyt
 *
 */
@Service
public class BtRecordService extends ModelDao<BtRecord>{

    @Autowired
    private BtRecordMapper btRecordMapper;

    @Autowired
    private AccountService accountService;
    
    @Autowired
	private KeyvalueService keyvalueService;
    
    @Autowired
    private BtAddrService btAddrService;
    
    @Autowired
    private ChargeService chargeService;
    
    
    private Logger logger = Logger.getLogger(BtRecordService.class);
    
    @Transactional
    public synchronized void doWithdraw(Customer user,double amount,String addr)throws Exception{
		double rate=keyvalueService.get(Keys.Charge).doubleValue()/100D;
		BtRecord bt=new BtRecord();
		bt.setCustomer_id(user.getId());
		bt.setCurrency_id(1);
		
		BtAddr Addr=btAddrService.getByAddr(addr);
		if(null!=Addr){
			bt.setAddr_id(Addr.getId());	
		}else{
			BtAddr _addr=new BtAddr();
			_addr.setAddr(addr);
			_addr.setCurrency_id(1);
			_addr.setCustomer_id(user.getId());
			_addr.setTag("");
			btAddrService.add(_addr);
			bt.setAddr_id(_addr.getId());
		}
		bt.setAmount(amount);
		bt.setCharge(Arith.mul(amount,rate));
		bt.setReal_amount(Arith.sub(amount,bt.getCharge()));
		bt.setResult(0);//待审核
		bt.setAddr(addr);
		bt.setCreate_time(DateUtils.getSystime());
		add(bt);
		
		Account account=accountService.getByCustomer(user.getId());
		account.setAmount(Arith.sub(account.getAmount(),amount));
		account.setFrozen_amount(Arith.add(account.getFrozen_amount(),bt.getAmount()));
		accountService.update(account);
    }
    
    public void add(BtRecord btRecord){
        btRecordMapper.add(btRecord);
    }
    
    public BtRecord get(Integer id){
        return btRecordMapper.get(id);
    }
    
    public BtRecord getByTXHash(String txhash){
        return btRecordMapper.getByTXHash(txhash);
    }
    
    public int delete(Integer id){
        return btRecordMapper.delete(id);
    }
    
    public int batchDelete(String[] ids){
    	return btRecordMapper.batchDelete(ids);
    }
    
    public List<BtRecord> list(Integer... ids){
    	return btRecordMapper.list(ids);
    }
    
    public List<BtRecord> page(Pager<BtRecord> page){
    	return btRecordMapper.page(page);
    }
    
    public List<BtRecord> query(Map<String,Object> conditions){
    	return btRecordMapper.query(conditions);
    }
    
    public int update(BtRecord btRecord){
    	return btRecordMapper.update(btRecord);
    }
    
    @Transactional
    public ActionResult pass(BtRecord btRecord,String prik)throws Exception{
        update(btRecord);//把result改为2
        
   		BtRecord bt=get(btRecord.getId());
   		Account account=accountService.getByCustomer(bt.getCustomer_id());
   		
   		if(null==account){
   			account=new Account();
   			account.setCreate_time(DateUtils.getSystime());
   			account.setCurrency_id(1);
   			account.setCustomer_id(bt.getCustomer_id());
   			accountService.add(account);
   			return new ActionResult(ErrorInfo.BalanceNotEnoughError);
   		}
   		
   		if(account.getFrozen_amount()>=bt.getAmount()){//查看是否有足够余额
   			
   			if(null!=bt&&null!=prik){
   	   			double charge=0.0D;//平台手续费
   	   			Charge chargeLog=null;
   	   			Keyvalue kv=keyvalueService.get(Keys.Charge);
   	   			if(null!=kv){//计算出 平台应收多少手续费，并创建手续费记录
   	   				double chargeRate=Double.valueOf(kv.getValue());
   	   				charge=Arith.mul(bt.getAmount(),(Arith.div(chargeRate,100,2)));
   	   				chargeLog=new Charge();
   	   				chargeLog.setAmount(charge);
   	   				chargeLog.setAddr(bt.getCustomer_addr());
   	   				chargeLog.setBt_id(bt.getId());
   	   				chargeLog.setCustomer_id(bt.getCustomer_id());
   	   				chargeLog.setCreate_time(DateUtils.getSystime());
   	   			}
   	   			

		         boolean test=false;
			    kv=keyvalueService.get(Keys.TestDev);
			    if(null!=kv&&1==kv.intValue()){
			    	test=true;
			    }
   	   			
   	   		     ETHInfo tr=ETHUtil.transfer(prik, bt.getAddr(), Arith.sub(bt.getAmount(),charge),test);
   	   			if(null!=tr&&200==tr.getStatus()){//提交转帐成功
   	   				if(null!=tr.getData()&&!tr.getData().isEmpty()){
   	   					String txhash=tr.getData().get("txhash");
   	   					bt.setTxhash(txhash);
   	   				}
   	   				bt.setUpdate_time(DateUtils.getSystime());
   	   				bt.setResult(4);//挖矿中
   					update(bt);
   	   			}else{
   	   				bt.setUpdate_time(DateUtils.getSystime());
   	   				bt.setResult(3);//提交失败
   					update(bt);
   					
   				   account.setFrozen_amount(account.getFrozen_amount()-bt.getAmount());//冻结提取金额
   		   		   account.setAmount(account.getAmount()+bt.getAmount());
   		   		   accountService.update(account);
   					
   	   			}
   	   		    chargeService.add(chargeLog);
   	   		}else{
   	   			return new ActionResult(ErrorInfo.LookAtError);
   	   		}
   		}else{
   			return new ActionResult(ErrorInfo.BalanceNotEnoughError);
   		}
   		
   		return null;
    }
    
    
    /**
     * 拒绝提币
     * @param btRecord
     */
    @Transactional
    public void refuse(BtRecord btRecord)throws Exception{
    	BtRecord bt=get(btRecord.getId());
    	Account account=accountService.getByCustomer(bt.getCustomer_id());
    	account.setFrozen_amount(account.getFrozen_amount()-bt.getAmount());
    	account.setAmount(account.getAmount()+bt.getAmount());
    	accountService.update(account);
    	update(btRecord);
    }
    
    /**
     * 提币成功
     * @param btRecord
     */
    @Transactional
    public void withdrawSuccess(BtRecord btRecord){
    	BtRecord bt=new BtRecord();
    	bt.setId(btRecord.getId());
    	bt.setResult(btRecord.getResult());
    	
    	Account account=accountService.getByCustomer(btRecord.getCustomer_id());
    	account.setFrozen_amount(Arith.sub(account.getFrozen_amount(),btRecord.getAmount()));
    	accountService.update(account);
    	update(bt);
    }
    
    @Transactional
    public void withdrawFail(BtRecord btRecord){
    	BtRecord bt=new BtRecord();
    	bt.setId(btRecord.getId());
    	bt.setResult(bt.getResult());
    	
    	Account account=accountService.getByCustomer(btRecord.getCustomer_id());
    	account.setFrozen_amount(account.getFrozen_amount()-btRecord.getAmount());
    	account.setAmount(account.getAmount()+btRecord.getAmount());
    	accountService.update(account);
    	update(bt);
    }
    
    
}